package com.tjbklx1.redis.chap06;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.tjbklx1.redis.JedisUtil;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

/**
 * chap6.1 自动补全最近联系人
 * @author tjbklx1
 * @date 2018-12-12
 */
public class App61 {

	public static void main(String[] args) throws InterruptedException, IOException {
		new App61().run();
	}

	public void run() throws InterruptedException, IOException {
		Jedis conn = JedisUtil.getJedisWithDB();
		testAddUpdateContact(conn);
	}

	public void testAddUpdateContact(Jedis conn) {
		System.out.println("\n----- testAddUpdateContact -----");
		conn.del("recent:user");

		System.out.println("Let's add a few contacts...");
		for (int i = 0; i < 10; i++) {
			addUpdateContact(conn, "user", "contact-" + ((int) Math.floor(i / 3)) + '-' + i);
		}
		System.out.println("Current recently contacted contacts");
		List<String> contacts = conn.lrange("recent:user", 0, -1);
		for (String contact : contacts) {
			System.out.println("  " + contact);
		}
		assert contacts.size() >= 10;
		System.out.println();

		System.out.println("Let's pull one of the older ones up to the front");
		addUpdateContact(conn, "user", "contact-1-4");  //增加一个新联系人,应该在第一的位置
		contacts = conn.lrange("recent:user", 0, 2);
		System.out.println("New top-3 contacts:");
		for (String contact : contacts) {
			System.out.println("  " + contact);
		}
		assert "contact-1-4".equals(contacts.get(0));
		System.out.println();

		System.out.println("Let's remove a contact...");
		removeContact(conn, "user", "contact-2-6");  //删除一个联系人
		contacts = conn.lrange("recent:user", 0, -1);
		System.out.println("New contacts:");
		for (String contact : contacts) {
			System.out.println("  " + contact);
		}
		assert contacts.size() >= 9;
		System.out.println();

		//  c  contact-2- 开头 分别查询自动补全列表,排序后,看结果是否相同
		System.out.println("And let's finally autocomplete on ");
		List<String> all = conn.lrange("recent:user", 0, -1);
		contacts = fetchAutocompleteList(conn, "user", "c");
		assert all.equals(contacts);
		List<String> equiv = new ArrayList<String>();
		for (String contact : all) {
			if (contact.startsWith("contact-2-")) {
				equiv.add(contact);
			}
		}
		contacts = fetchAutocompleteList(conn, "user", "contact-2-");
		Collections.sort(equiv);
		Collections.sort(contacts);
		assert equiv.equals(contacts);
		conn.del("recent:user");
	}

	/**
	 * 增加最近联系人
	 * @param conn
	 * @param user
	 * @param contact
	 */
	public void addUpdateContact(Jedis conn, String user, String contact) {
		String acList = "recent:" + user;
		Transaction trans = conn.multi();
		trans.lrem(acList, 0, contact); // 如果联系人存在先删除 ( lrem 0 移除表中所有与 VALUE 相等的值。)
		trans.lpush(acList, contact);//增加联系人到最左边
		trans.ltrim(acList, 0, 99);//保留前100个
		trans.exec();
	}

	/**
	 * 删除联系人
	 * @param conn
	 * @param user
	 * @param contact
	 */
	public void removeContact(Jedis conn, String user, String contact) {
		conn.lrem("recent:" + user, 0, contact); // 如果联系人存在先删除 ( lrem 0 移除表中所有与 VALUE 相等的值。)
	}

	/**
	 * 根据key,前缀查询 联系人列表
	 * @param conn
	 * @param user
	 * @param prefix
	 * @return
	 */
	public List<String> fetchAutocompleteList(Jedis conn, String user, String prefix) {
		List<String> candidates = conn.lrange("recent:" + user, 0, -1);
		List<String> matches = new ArrayList<String>();
		for (String candidate : candidates) {
			if (candidate.toLowerCase().startsWith(prefix)) {
				matches.add(candidate);
			}
		}
		return matches;
	}
}
